/***
 * * PROJECT
 * *    ATaG
 * * VERSION
 * *    $Revision: 1.25 $
 * * DATE
 * *    $Date: 2008/10/07 12:57:38 $
 * * LOG
 * *    $Log: NodeInfo.java,v $
 * *    Revision 1.25  2008/10/07 12:57:38  animesh
 * *    removed GPL License [will re-add to all files later]
 * *
 * *    Revision 1.24  2007/11/20 22:44:56  animesh
 * *    no message
 * *
 * *    Revision 1.23  2007/08/17 20:37:51  animesh
 * *    no message
 * *
 * *    Revision 1.22  2007/08/17 19:45:54  animesh
 * *    regionLabel and abilityString added
 * *
 * *    Revision 1.21  2007/01/29 18:44:37  lmottola
 * *    Refactored task assignment code.
 * *
 * *    Revision 1.20  2007/01/29 17:48:01  lmottola
 * *    Added debug info in toString() method.
 * *
 * *    Revision 1.19  2006/12/30 09:26:49  animesh
 * *    fixed minor typo.
 * *
 * *    Revision 1.18  2006/12/20 23:05:07  lmottola
 * *    Removed reference to ATaGProgram in NodeInfo.
 * *
 * *    Revision 1.17  2006/12/14 23:06:35  lmottola
 * *    Added constructor for compiler use.
 * *
 * *    Revision 1.16  2006/12/14 05:15:15  lmottola
 * *    Moved Estimator in atag.compiler and various cleanup.
 * *
 * *    Revision 1.15  2006/11/03 23:09:34  lmottola
 * *    Changed nodeAttributes package.
 * *
 * *    Revision 1.14  2006/11/03 23:08:17  lmottola
 * *    Traffic application beta running.
 * *
 * *    Revision 1.13  2006/10/30 23:53:56  animesh
 * *    added new function to return the value of the regionID.. perhaps this needs more work, as a node may have multiple regionIDs.
 * *
 * *    Revision 1.12  2006/10/27 01:28:28  lmottola
 * *    Debugging support added.
 * *
 * *    Revision 1.11  2006/10/27 00:11:58  lmottola
 * *    Automatic generation of attribute describing the tasks running on a node.
 * *
 * *    Revision 1.10  2006/10/25 22:50:49  lmottola
 * *    Startup file created.
 * *
 * *    Revision 1.9  2006/10/25 19:06:20  lmottola
 * *    Refactored myLocation().
 * *
 * *    Revision 1.8  2006/10/25 18:24:02  lmottola
 * *    Added getMyLocation() method.
 * *
 * *    Revision 1.7  2006/10/24 00:08:50  lmottola
 * *    Added sendingCost field.
 * *
 * *    Revision 1.6  2006/10/21 01:05:12  lmottola
 * *    Changed method getNodeAttributes.
 * *
 * *    Revision 1.5  2006/10/20 00:30:01  lmottola
 * *    Added constructor.
 * *
 * *    Revision 1.4  2006/10/20 00:27:15  lmottola
 * *    Made NodeAttribute abstract.
 * *
 * *    Revision 1.3  2006/10/19 21:49:22  lmottola
 * *    Added getAttributes method.
 * *
 * *    Revision 1.2  2006/10/19 21:21:52  lmottola
 * *    Added CVS preamble.
 * *
 * *
 * *   ATaG (Abstract Task Graph) - Data-driven Macroprogramming for
 * *                                Sensor Networks
 * *
 ***/

package atag.runtime;

import bsh.This;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import atag.runtime.ln.nodeAttributes.NodeAttribute;
import atag.runtime.ln.nodeAttributes.SetAttribute;

public class NodeInfo {

    private Vector attributes;

    private Vector assignedTasks;

    private int myId;

    private NodeLocation myLocation;

    private int sendingCost;

    private IClock clock;

    private String regionLabel;
    private int regionID;

    private String abilityString;
    //to store the ability string from the topology file.
    //Used when creating the startup files

    public static final String ASSIGNED_TASK_ATTR_NAME = "runningTasks";
    
    public static final String NODE_ID_ATTR_NAME = "NodeID";
    
    // Indicates invalid/unknown Region Identifier for mobile nodes
    public static final int REGION_ID_INVALID = -1;

    // Indicates dynamic/unknown IP address 
    public static String PHYSICAL_ADDR_IP_DYNAMIC="0.0.0.0";

    // For compiler use
    public NodeInfo(int myId, NodeLocation myLocation, Collection nodeAttributes) {

        attributes = new Vector(nodeAttributes);
        this.myId = myId;
        this.myLocation = myLocation;
        this.assignedTasks = new Vector();
        this.regionLabel = "";
        this.abilityString = "";
    }

    public void assignTasks(Set tasks) {

        this.assignedTasks = new Vector(tasks);

        // Remove any previously assignedTask attribute
        Iterator it = attributes.iterator();
        while (it.hasNext()) {
            NodeAttribute attr = (NodeAttribute) it.next();
            if (attr.getKey().equals(ASSIGNED_TASK_ATTR_NAME)) {
                attributes.remove(attr);
                break;
            }
        }

        attributes.add(new SetAttribute(ASSIGNED_TASK_ATTR_NAME, assignedTasks));
    }

    // For runtime use
    public NodeInfo(int myId, NodeLocation myLocation,
            Collection nodeAttributes, int sendingCost, List assignedTasks, IClock clock) {

        attributes = new Vector(nodeAttributes);
        this.sendingCost = sendingCost;
        this.myId = myId;
        this.myLocation = myLocation;
        this.clock = clock;
        this.assignedTasks = new Vector(assignedTasks);

        // Automatic generation of attributes - assigned atsks
        attributes
                .add(new SetAttribute(ASSIGNED_TASK_ATTR_NAME, assignedTasks));

        // TODO: Generate an attribute for location
        this.regionLabel = "";
        this.abilityString = "";
    }

    public void addNodeAttribute(NodeAttribute attr) {
        attributes.add(attr);
    }

    public Collection getNodeAttributes() {
        return attributes;
    }

    public Object getAttributeByName(String name) {

        Iterator it = attributes.iterator();
        while (it.hasNext()) {
            NodeAttribute attr = (NodeAttribute) it.next();
            if (attr.getKey().equals(name)) {
                return attr.getValue();
            }
        }
        return null;
    }

    public int getMyId() {
        return myId;
    }

    public NodeLocation getMyLocation() {
        return this.myLocation;
    }

    public boolean isTaskAssigned(int taskID) {
        return assignedTasks.contains(new Integer(taskID));
    }

    public int getSendingCost() {
        return sendingCost;
    }

    public IClock getClock() {
        return clock;
    }

    public void debugPrint(String debugMessage) {
        System.out.println(myId + ": " + debugMessage + " at time "
                + clock.getTime() + " " + clock.getDate());
        System.out.flush();
    }

    public String toString() {

        String ret = "NodeInfo id: "+myId;

        Iterator it = attributes.iterator();
        while (it.hasNext()) {
            ret = ret.concat("\nAttribute "+ ((NodeAttribute)it.next()).toString());
        }

        return ret;
    }

    public void setRegionLabel(String newRegionLabel) {
        this.regionLabel = newRegionLabel;
    }

    public String getRegionLabel(){
        return this.regionLabel;
    }

    public void setAbilityString(String newAbilityString){
        this.abilityString = newAbilityString;
    }

    public String getAbilityString(){
        return this.abilityString;
    }


    public void setRegionID(int ID){
        this.regionID = ID;
    }

    public int getRegionID() {
        return this.regionID;
    }

}
